﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FNN.CustomFunctions;
using FNN.Helpers;
using FNN.NetworkMasters;
using FNN.Networks;
using FNN.SourcePoints;
using Microsoft.Win32;
using System.IO;
using FNN.Helpers.IO;
using FNN.Factories.Helpers;
using FNN.Helpers.DataSource;
using FNN.Factories.Networks;

namespace GraphicFNN.Pages
{
    /// <summary>
    ///     Логика взаимодействия для CreationPage.xaml
    /// </summary>
    public partial class CreationPage : Page
    {
        public CreationPage()
        {
            InitializeComponent();
        }

        private void ChbRandom_OnChecked(object sender, RoutedEventArgs e)
        {
            var grayBrush = Brushes.LightGray;
            TxtNetworkName.IsEnabled = false;
            TxtNetworkName.Background = grayBrush;
            TxtInputCount.IsEnabled = false;
            TxtInputCount.Background = grayBrush;
            TxtLayerCount.IsEnabled = false;
            TxtLayerCount.Background = grayBrush;
            TxtLayerNeuronCount.IsEnabled = false;
            TxtLayerNeuronCount.Background = grayBrush;
            TxtOutputCount.IsEnabled = false;
            TxtOutputCount.Background = grayBrush;
            CmbFunctions.IsEnabled = false;
        }

        private void ChbRandom_OnUnchecked(object sender, RoutedEventArgs e)
        {
            var whiteBrush = Brushes.White;
            TxtNetworkName.IsEnabled = true;
            TxtNetworkName.Background = whiteBrush;
            TxtInputCount.IsEnabled = true;
            TxtInputCount.Background = whiteBrush;
            TxtLayerCount.IsEnabled = true;
            TxtLayerCount.Background = whiteBrush;
            TxtLayerNeuronCount.IsEnabled = true;
            TxtLayerNeuronCount.Background = whiteBrush;
            TxtOutputCount.IsEnabled = true;
            TxtOutputCount.Background = whiteBrush;
            CmbFunctions.IsEnabled = true;
        }

        private void BtnCreate_OnClick(object sender, RoutedEventArgs e)
        {
            var helper = DataSourceHelperFactory.CreateHelper((NetworkTypes)CmbType.SelectedIndex, TxtSourcePath.Text);
            var masterFactory = new NetworkMasterFactory(helper);
            var chartWindow = new ChartWindow();

            NetworkMaster netMaster = masterFactory.CreateMaster((NetworkTypes)CmbType.SelectedIndex);
            Network targetNetwork = NetworkFactory.CreateNetwork((NetworkTypes)CmbType.SelectedIndex,
                new FNN.Options.NetworkOptions(Convert.ToInt32(TxtInputCount.Text), Convert.ToInt32(TxtLayerCount.Text),
                            Convert.ToInt32(TxtLayerNeuronCount.Text),
                            new List<FunctionTypes> { (FunctionTypes)(CmbFunctions.SelectedIndex - 1) },
                            Convert.ToInt32(TxtOutputCount.Text)));

            netMaster.GenerationChanged += chartWindow.CatchIterationChanged;
            netMaster.GenerationResultsImproved += chartWindow.CatchResultsImproved;

            if (netMaster == null) return;
            targetNetwork.NetworkName = TxtNetworkName.Text;
            netMaster.IterationsLimit = 3000;
            netMaster.TimeLimit = 0;
            chartWindow.Show();

            var backgroundTask = Task.Factory.StartNew(() =>
            {
                var serializationHelper = new SerializationHelper();

                var resultNetwork = netMaster.TrainMultiNetwork(targetNetwork);
                var targetName = "";
                Dispatcher.Invoke(() =>
                {
                    chartWindow.Close();
                    targetName = TxtNetworkName.Text;
                    File.Copy(TxtSourcePath.Text, targetName + ".csv", true);
                    serializationHelper.WriteBinary(resultNetwork, targetName + ".fnn");
                });
            });
        }

        private void BtnSelectSource_OnClick(object sender, RoutedEventArgs e)
        {
            var fileBrowser = new OpenFileDialog
            {
                CheckFileExists = true,
                Multiselect = false,
                Filter = "CSV|*.csv"
            };
            fileBrowser.ShowDialog();
            TxtSourcePath.Text = fileBrowser.FileName;
        }
    }
}